package plantasvszombies;

import org.apache.wicket.AttributeModifier;

import java.util.List;

import jardinzen.JardinZenPage;

import org.apache.wicket.request.mapper.parameter.PageParameters;
import org.apache.wicket.request.resource.ContextRelativeResource;
import org.apache.wicket.ajax.AjaxRequestTarget;
import org.apache.wicket.ajax.markup.html.AjaxFallbackLink;
import org.apache.wicket.ajax.markup.html.AjaxLink;
import org.apache.wicket.markup.html.basic.Label;
import org.apache.wicket.markup.html.form.Button;
import org.apache.wicket.markup.html.form.ChoiceRenderer;
import org.apache.wicket.markup.html.form.DropDownChoice;
import org.apache.wicket.markup.html.form.Form;
import org.apache.wicket.markup.html.form.TextField;
import org.apache.wicket.markup.html.image.Image;
import org.apache.wicket.markup.html.link.Link;
import org.apache.wicket.markup.html.list.ListItem;
import org.apache.wicket.markup.html.list.PropertyListView;
import org.apache.wicket.markup.html.panel.FeedbackPanel;
import org.apache.wicket.markup.html.WebMarkupContainer;
import org.apache.wicket.markup.html.WebPage;
import org.apache.wicket.model.CompoundPropertyModel;
import org.apache.wicket.model.LoadableDetachableModel;
import org.apache.wicket.model.Model;
import org.apache.wicket.model.PropertyModel;

import applicationModels.*;
import dominio.*;
import exceptions.*;

public class GamePage extends WebPage {
	private static final long serialVersionUID = 1L;
	private Juego game;
	private Label alert;

	public GamePage(final PageParameters parameters) {

		this.game = Juego.makeJuego();
	    
		this.createGameGrid();
		this.add(new Label("puntos",new PropertyModel<Integer>(this.game.getUsuario(), "puntos")));
		this.addAlertPanel();
		
        this.createFormActions();
		this.createFormPlantar();
		
		this.addPanelDeNotificaciones();		

		addSeccionAtacar();
	}
	
	@SuppressWarnings("serial")
	protected void addPanelDeNotificaciones() {
		this.add(new PropertyListView<String>("mensajesLog", new PropertyModel<List<String>>(this.game, "mensajesLog")) {
			@Override
			protected void populateItem(final ListItem<String> item) {
				item.add(new Label("mensaje", item.getModelObject()));
			}
		});
	}
	
    protected void createFormActions(){
    	Form<Juego> actions = new Form<Juego>("acciones", new CompoundPropertyModel<Juego>(this.game));
		this.generarAcciones(actions);
		this.add(actions);
    }
    
	@SuppressWarnings("serial")
	private void generarAcciones(Form<Juego> parent) {
		parent.add(new Button("goToJardinZenButton") {
			@Override
			public void onSubmit() {
				irAlJardin(game);
			}
		});
		
		parent.add(new Button("goToMejorasPeashooter") {
			@Override
			public void onSubmit() {
				Planta plant = game.getUsuario().getJardinZen()
						.getPlanta("Peashooter");
				Mejorar appMejorar = new Mejorar(game.getUsuario(), plant);
				GamePage.this.hackMejoraPea(appMejorar);
			}
		});
		
		parent.add(new Button("goToAlmanaque") {
			@Override
			public void onSubmit() {
				irAlAlmanaque(game);
			}
		});
		
		parent.add(new Button("restartGameButton") {
			@Override
			public void onSubmit() {
				game = Juego.makeJuego();
				System.out.println("Game restarted");
			}
		});
	}
    
	@SuppressWarnings("serial")
	protected void createFormPlantar(){
		Form<Juego> formPlantaPlantar = new Form<Juego>("plantaPlantar", new CompoundPropertyModel<Juego>(this.game)) {
			@Override
			protected void onSubmit() {
				alert("Has seleccionado un "+ game.getPlantaPlantar().getNombre() + " para plantar ", true);
			}
		};
		this.createPlantSelector(formPlantaPlantar);
		this.add(formPlantaPlantar);
	}
	
	/**
	 * Agrega la seccion de seleccion de zombies
	 */
	@SuppressWarnings("serial")
	protected void addSeccionAtacar() {
		Form<Juego> formZombieAtacante = new Form<Juego>("zombieAtacante", new CompoundPropertyModel<Juego>(this.game)) {
			@Override
			protected void onSubmit() {
				alert(game.getZombieAtacante().getNombre() +" listo para atacar", false);
			}
		};
		this.createZombieSelector(formZombieAtacante);
		this.add(formZombieAtacante);
	}

	/**
	 * Elegir de entre las plantas disponibles para plantar
	 * @param parent, el formulario que setea la planta elegida
	 */
	@SuppressWarnings("serial")
	private void createPlantSelector(Form<Juego> parent) {
		// Que planta elegir
		parent.add(new DropDownChoice<Planta>("plantaPlantar", 
				new LoadableDetachableModel<List<Planta>>() {
					@Override
					protected List<Planta> load() {
						return game.getPlantasDisponibles();
					}
				}));

		parent.add(new Button("plantar") {
			@Override
			public void onSubmit() {
				alert("Planta seleccionada para plantar: "+ game.getPlantaPlantar(), false);						
			}
		});
	}

	@SuppressWarnings("serial")
	protected void createZombieSelector(Form<Juego> parent) {

		parent.add(new DropDownChoice<Zombie>("zombieAtacante.nombre",
				new LoadableDetachableModel<List<Zombie>>() {

					@Override
					protected List<Zombie> load() {
						return game.getZombies();
					}

				}, new ChoiceRenderer<Zombie>() {
					@Override
					public Object getDisplayValue(Zombie object) {
						return object;
					}
				})
		);
		
		parent.add(new Button("elegirZombie"));
	}

	@SuppressWarnings({"serial", "rawtypes"})
	protected void createGameGrid() {

		this.add(new PropertyListView<Fila>("filas",new CompoundPropertyModel<List<Fila>>(this.game.getFilas())) {
			@Override
			protected void populateItem(final ListItem<Fila> item) {
				populateCasilleros(item);
				
				item.add(new Link("ataqueZombieBtn") {
					@Override
					public void onClick() {
						alert("El zombie "+ game.getZombieAtacante().getNombre() +" te esta atacando", false);
						game.setFilaParaAtacar(item.getIndex()+1);
						game.pelear();
					}
				});
			}
		});
	}

	@SuppressWarnings({"serial", "rawtypes"})
	protected void populateCasilleros(ListItem<Fila> it) {
		
		it.add(new PropertyListView<Casillero>("casillero", it.getModelObject().getCasilleros()) {
			@Override
			protected void populateItem(final ListItem<Casillero> item) {
				
				Link desPlantar = new Link("buttonDesPlantar") {
					@Override
					public void onClick() {
						if(item.getModelObject().ocupado()) {
							alert("Has desplantado un " + game.getPlantaPlantar().getNombre(), true);
							item.getModelObject().desplantar();
						} else {
							try {
								item.getModelObject().plantar(game.getPlantaPlantar());
								alert(" Has plantado un " + game.getPlantaPlantar().getNombre(), true);
							} catch (ErrorTerreno e) {
								alert("Terreno incorrecto!", false);
							}
						}
					}
				};
					
				/*AjaxLink desPlantar = new AjaxLink("buttonDesPlantar") {
					@Override
					public void onClick(AjaxRequestTarget target) {
						System.out.println("dsadas");
						/*
						if(item.getModelObject().ocupado()) {
							//target.appendJavaScript("alert('Desplantando');");
							info("Has desplantado un " + game.getPlantaPlantar().getNombre());
							item.getModelObject().desplantar();
						} else {
							try {
								item.getModelObject().plantar(game.getPlantaPlantar());
								info(" Has plantado un " + game.getPlantaPlantar().getNombre());
							} catch (ErrorTerreno e) {
								//target.appendJavaScript("alert('Error de terreno');");
							}
						}
						
						target.add(item);
					}
				};*/
				
				item.add(desPlantar);

				// Imagen de la planta que ocupa el casillero
				Image img = new Image("imgPlanta", new ContextRelativeResource(	"plantas/"+ item.getModelObject().getNombreOcupante()+ ".png"));
				
				// CSS para el tipo de terreno
				String type = item.getModelObject().getTerrestre() ? "grass" : "aqua";
				img.add(new AttributeModifier("class","imgPlanta " + type));
				
				desPlantar.add(img);
			}
		});

	}
	
	protected void addAlertPanel() {
		this.alert = new Label("exceptions");
		this.add(this.alert);
	}
	
	protected void alert(String texto, boolean buena) {
		String type = buena ? "notify" : "alert";
		this.alert.add(new AttributeModifier("class", type));
		this.alert.add(new AttributeModifier("value", texto));
	}

	protected void hackMejoraPea(Mejorar appMej) {
		UpgradePlantPage upgrade = new UpgradePlantPage(this, this.game,
				this.game.getUsuario().getJardinZen().getPlanta("Peashooter"));
		this.setResponsePage(upgrade);
	}

	protected void irAlJardin(Juego g) {
		JardinZenPage jardin = new JardinZenPage(this, g);
		this.setResponsePage(jardin);
	}
	protected void irAlAlmanaque(Juego g) {
	AlmanaqueZombiesPage alma = new AlmanaqueZombiesPage(this, g);
		this.setResponsePage(alma);
	}
	

}
